#ifndef RMD_CALCULATE_TOOLS_H_
#define RMD_CALCULATE_TOOLS_H_

#include <opencv2/core/core.hpp>

namespace rmd {

template <typename T>
inline T min(T a, T b) {
  T result = ((a) > (b)) ? (b) : (a);
  return result;
}

template <typename T>
inline T max(T a, T b) {
  T result = ((a) > (b)) ? (a) : (b);
  return result;
}

class CalcuateTools {
 public:
  CalcuateTools();
  virtual ~CalcuateTools();

  static CalcuateTools* GetInstance();
  static CalcuateTools* instance_;

  cv::Point2f GetXorYToPt(cv::Point2f pt1, cv::Point2f pt2, double t,
                      bool yFlag = true);
  float GetXorY(cv::Point pt1, cv::Point pt2, double t, bool yFlag = true);

  cv::Point2f GetPointByDoublePoint(cv::Point2f pt1, cv::Point2f pt2, double t,
                                     bool yFlag);

  void CalcLineKBR(cv::Point pt1, cv::Point pt2, double& fk, double& fb,
                   double& frho, int& nDistance);
  float CalRho(cv::Point pt1, cv::Point pt2);

  double PointToLineDistByPoint(cv::Point pt, cv::Point bpt1, cv::Point bpt2);

  cv::Point2f GetCrossPoint(double a1, double b1, double a2, double b2);
  cv::Point2f GetCrossPoint(cv::Point point1, cv::Point point2,
                            cv::Point point3, cv::Point point4);

  double GetDoubleLineAngle(double k1, double k2);

  short GetInt(short a,short b,short c);

  void GetBinaryValue(short s,short &a,short &b,short &c);

  void ShowPointsInMat(cv::Mat& input, std::vector<cv::Point> input_points,
                       cv::Scalar color);
};
}

#endif
